// @Author EthanScriptOn
// @Desc
package extend_parser

import (
	"database/sql"
	"fmt"
	"gitee.com/fatzeng/srf_switch_stream_bridge/bridge"
	"gitee.com/fatzeng/srf_switch_stream_bridge/framework/actuator"
	"reflect"
)

type MysqlQueryResponseParser struct {
}

func (m *MysqlQueryResponseParser) Parse(ctx *actuator.SrfSwitchBridgeActuatorContext, config *bridge.BridgeConfig, response interface{}) (interface{}, error) {
	rows, ok := response.(*sql.Rows)
	if !ok {
		return nil, fmt.Errorf("response is not *sql.Rows")
	}

	dest := reflect.New(config.ResultType).Interface()
	elem := reflect.ValueOf(dest).Elem()
	if elem.Kind() != reflect.Slice {
		return nil, fmt.Errorf("result type must be a slice")
	}
	elemType := elem.Type().Elem()
	if elemType.Kind() != reflect.Struct {
		return nil, fmt.Errorf("result type must be a struct")
	}
	return m.FetchRecords(rows, elemType)
}

func (m *MysqlQueryResponseParser) FetchRecords(rows *sql.Rows, destType reflect.Type) (response []interface{}, err error) {
	for rows.Next() {
		newInstance := reflect.New(destType).Elem()
		values := make([]interface{}, 0)
		for i := range values {
			values[i] = new(interface{})
		}
		if err = rows.Scan(values...); err != nil {
			return
		}
		for i := 0; i < newInstance.NumField(); i++ {
			fieldValue := reflect.ValueOf(values[i]).Elem()
			newInstance.Field(i).Set(fieldValue)
		}
		response = append(response, newInstance.Interface())
	}
	return response, rows.Err()
}
